package action.RDD基本转换操作2

import org.apache.spark.{SparkConf, SparkContext}

/**
  * Repartition
  * Reshuffle the data in the RDD randomly to create either more or fewer partitions and balance it across them.
  * This always shuffles all data over the network.
  * 随机重新调整RDD中的数据以创建更多或更少的分区并在它们之间进行平衡。
  * 这总是随机打乱网络上的所有数据。
  *
  * @author wdmcode@aliyun.com
  * @version 1.0.0
  * @date 2018/11/8
  */
object SparkRepartition {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf()
    conf.setAppName("SparkParallelize")
    conf.setMaster("local[2]")

    val spark = new SparkContext(conf)

    val rdd = spark.parallelize(1 to 10)
    println(rdd.partitions.size) // 2

    /**
      * 注意：
      * repartition可以减少分区数，也可以增加分区数
      */
    val coalRDD = rdd.repartition(3)

    println(coalRDD.partitions.size)

    /**
      * repartition和coalesce的用法和比较
      * 他们两个都是RDD的分区进行重新划分，repartition只是coalesce接口中shuffle为true的简易实现，（假设RDD有N个分区，需要重新划分成M个分区）
      *
      * 1）、N<M。一般情况下N个分区有数据分布不均匀的状况，利用HashPartitioner函数将数据重新分区为M个，这时需要将shuffle设置为true。
      *
      * 2）如果N>M并且N和M相差不多，(假如N是1000，M是100)那么就可以将N个分区中的若干个分区合并成一个新的分区，最终合并为M个分区，
      * 这时可以将shuff设置为false，在shuffl为false的情况下，如果M>N时，coalesce为无效的，不进行shuffle过程，父RDD和子RDD之间是窄依赖关系。
      *
      * 3）如果N>M并且两者相差悬殊，这时如果将shuffle设置为false，父子ＲＤＤ是窄依赖关系，他们同处在一个Ｓｔａｇｅ中，
      * 就可能造成spark程序的并行度不够，从而影响性能，如果在M为1的时候，为了使coalesce之前的操作有更好的并行度，可以将shuffle设置为true。
      *
      * 总之：如果shuff为false时，如果传入的参数大于现有的分区数目，RDD的分区数不变，也就是说不经过shuffle，是无法将RDDde分区数变多的。
      */


    spark.stop()
  }

}
